#include "Game.h"

IGame* createGame( HINSTANCE hInst, HWND hWnd )
{
	return new Game( hInst, hWnd );
}

Game::Game( HINSTANCE hInst, HWND hWnd ) :
	m_input( hInst, hWnd )
{

	// initialize camera
	m_camera.hand = Camera::RIGHTHANDED;

	m_camera.eye = float3( 0, 0, 20.f );
	m_camera.at  = float3( 0, 0, 0 );
	m_camera.up  = float3( 0, 1, 0 );

	m_camera.projectionType = Camera::PERSPECTIVE_FOV;
	m_camera.perspectiveFov.fovy = D3DXToRadian(45.f);
	m_camera.perspectiveFov.aspect = 1024.f/768.f;

	m_camera.zn = 1.0f;
	m_camera.zf = 100.0f;

	// initialize polygon
	initializeBoxArray();
	initializePlayers();
}

Game::~Game()
{
	m_polygonView.destroy();
	m_d3dDevice = 0;
}

void Game::onCreateGraphics( D3DDevice device )
{
	m_d3dDevice = device;
	m_polygonView.initialize( m_d3dDevice );

	m_d3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );

	float44 world = identity44();
	float44 view = m_camera.view();
	float44 proj = m_camera.projection();

	m_d3dDevice->SetTransform( D3DTS_WORLD, &world );
	m_d3dDevice->SetTransform( D3DTS_VIEW, &view );
	m_d3dDevice->SetTransform( D3DTS_PROJECTION, &proj );
	
}

void Game::onResetGraphics( D3DDevice device )
{
	//TODO: Add code to handle lost device ( resizing issue )

	m_d3dDevice = device;

	m_polygonView.destroy();
	m_polygonView.initialize( m_d3dDevice );

	m_d3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );

	float44 view = m_camera.view();
	float44 proj = m_camera.projection();

	m_d3dDevice->SetTransform( D3DTS_VIEW, &view );
	m_d3dDevice->SetTransform( D3DTS_PROJECTION, &proj );
}

void Game::onLostGraphics()
{
}

void Game::onFrameMove(float dt)
{
	updatePlayerBox(dt);
	enemyUpdate(dt);
}

void Game::onFrameRender(float dt)
{
		float44 world = identity44();

		for(int i=0; i<7; i++){
			m_polygonView.setup(boxArray[i].m_polygon_0, float4( 1.0f, 1.0f, 1.0f, 1.0f ) );
			m_polygonView.render( world );

			m_polygonView.setup(boxArray[i].m_polygon_1, float4( 1.0f, 1.0f, 1.0f, 1.0f ) );
			m_polygonView.render( world );
		}

		drawPlayerBox();
		drawAIBox();
}

void Game::onDestroyGraphics()
{
}

void Game::initializeBoxArray(){
	srand(time(NULL));
	float centerX, centerY;
	int scrn_wide_Y = 10;
	int scrn_wide_X = 15;

	for(int i=0; i<7; i++){
		centerY=(float)(rand()%scrn_wide_Y)-scrn_wide_Y/2; 
		centerX=(float)(rand()%scrn_wide_X)-scrn_wide_X/2;

		boxArray[i].m_polygon_0.push_back( float3(-0.2f+centerX,-0.2f+centerY, 0 ) );
		boxArray[i].m_polygon_0.push_back( float3( 0.2f+centerX,-0.2f+centerY, 0 ) );
		boxArray[i].m_polygon_0.push_back( float3(-0.2f+centerX, 0.2f+centerY, 0 ) );

		boxArray[i].m_polygon_1.push_back( float3(-0.2f+centerX, 0.2f+centerY, 0 ) );		
		boxArray[i].m_polygon_1.push_back( float3( 0.2f+centerX,-0.2f+centerY, 0 ) );
		boxArray[i].m_polygon_1.push_back( float3( 0.2f+centerX, 0.2f+centerY, 0 ) );

		boxArray[i].center = D3DXVECTOR3(centerX, centerY, 0.2f);
		boxArray[i].boxN = D3DXVECTOR3(centerX, centerY + 0.2f, 0.0f);
		boxArray[i].boxS = D3DXVECTOR3(centerX, centerY - 0.2f, 0.0f);
		boxArray[i].boxE = D3DXVECTOR3(centerX + 0.2f, centerY, 0.0f);
		boxArray[i].boxW = D3DXVECTOR3(centerX - 0.2f, centerY, 0.0f);

	}
}

void Game::initializePlayers(){
	poly::Polygon A;
	A.push_back(float3(-1,0,0));
	A.push_back(float3(0,-1,0));
	A.push_back(float3(0,1,0));
	A.push_back(float3(0,1,0));
	Contact C;
	bool p=intersect(C,A,float3(-3,0,0),3);
	//Player
	playerBox.center = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	
	playerBox.m_polygon_0.push_back( float3(-0.2f,-0.2f, 0 ) );
	playerBox.m_polygon_0.push_back( float3( 0.2f,-0.2f, 0 ) );
	playerBox.m_polygon_0.push_back( float3(-0.2f, 0.2f, 0 ) );

	playerBox.m_polygon_1.push_back( float3(-0.2f, 0.2f, 0 ) );		
	playerBox.m_polygon_1.push_back( float3( 0.2f,-0.2f, 0 ) );
	playerBox.m_polygon_1.push_back( float3( 0.2f, 0.2f, 0 ) );

	playerVis = Visibility(float3 (0.0f, 0.0f, 0.0f), 3.14/3, 10.0f);
	playerSpeed = 9;
	playerMoveTo = float3(rand()%10-5, rand()%10-5, 0.0f);
	rotationalSpeed = 0.0f;

	//AI
	aiBox.center = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	
	aiBox.m_polygon_0.push_back( float3(-0.2f,-0.2f, 0 ) );
	aiBox.m_polygon_0.push_back( float3( 0.2f,-0.2f, 0 ) );
	aiBox.m_polygon_0.push_back( float3(-0.2f, 0.2f, 0 ) );

	aiBox.m_polygon_1.push_back( float3(-0.2f, 0.2f, 0 ) );		
	aiBox.m_polygon_1.push_back( float3( 0.2f,-0.2f, 0 ) );
	aiBox.m_polygon_1.push_back( float3( 0.2f, 0.2f, 0 ) );

	aiMoveTo = float3(rand()%10-5, rand()%10-5, 0.0f);
	aiBox.center += aiMoveTo;
}

void Game::updatePlayerBox(float dt){
	IInput::KEYSTATE a=m_input.keyState();
	IInput::MOUSESTATE b=m_input.mouseState();

	if( a.keys[DIK_A] &  0x80)	 playerBox.center		+= D3DXVECTOR3(-1.0f*playerSpeed, 0.0f, 0.0f) * dt ;
	if( a.keys[DIK_D] &  0x80)	 playerBox.center		+= D3DXVECTOR3(1.0f*playerSpeed, 0.0f, 0.0f) * dt ;
	if( a.keys[DIK_W] &  0x80)	 playerBox.center		+= D3DXVECTOR3(0.0f, 1.0f*playerSpeed, 0.0f) * dt ;
	if( a.keys[DIK_S] &  0x80)	 playerBox.center		+= D3DXVECTOR3(0.0f, -1.0f*playerSpeed, 0.0f) * dt ;

	rotationalSpeed = b.x*dt;

	playerMoveTo = playerBox.center;
	playerVis.updateTri(playerMoveTo, rotationalSpeed);
}

void Game::drawPlayerBox(){
		float44 move = translation(playerMoveTo);

		float44 rotate;
		D3DXMatrixRotationZ(&rotate, rotationalSpeed);
		playerBox.m_polygon_0=playerBox.m_polygon_0.transform(rotate);
		playerBox.m_polygon_1=playerBox.m_polygon_1.transform(rotate);

		m_polygonView.setup(playerBox.m_polygon_0, float4( 1.0f, 0.6f, 0.6f, 1.0f ) );
		m_polygonView.render( move );
		m_polygonView.setup(playerBox.m_polygon_1, float4( 1.0f, 0.6f, 0.6f, 1.0f ) );
		m_polygonView.render( move );

		if(playerVis.canSee(0.2, aiBox.center))	
			m_polygonView.setup(playerVis.getPoly(), float4( 0.0f, 0.0f, 1.0f, 0.0f ) );
		else					
			m_polygonView.setup(playerVis.getPoly(), float4( 0.0f, 0.2f, playerVis.getProp(VIS_VISPERC)/100.0f, 0.6f ) );
		m_polygonView.render( move );
}

void Game::drawAIBox(){
		float44 move = translation(aiMoveTo);

		m_polygonView.setup(aiBox.m_polygon_0, float4( 0.0f, 1.0f, 0.0f, 1.0f ) );
		m_polygonView.render( move );
		m_polygonView.setup(aiBox.m_polygon_1, float4( 0.0f, 1.0f, 0.0f, 1.0f ) );
		m_polygonView.render( move );
}

void Game::enemyUpdate(float dt){
}

void Game::writeToFile(float f){
	ofstream file;
	file.open("test.txt");
	file << f <<endl;
	file.close();
}